// generic_demo.dart - 演示Dart中的泛型特性

void main() {
  // 1. 使用泛型集合字面量
  print('--- 泛型集合示例 ---');
  var names = <String>['Seth', 'Kathy', 'Lars'];
  var uniqueNames = <String>{'Seth', 'Kathy', 'Lars'};
  var pages = <String, String>{
    'index.html': 'Homepage',
    'robots.txt': 'Hints for web robots',
    'humans.txt': 'We are people, not machines',
  };

  print('Names list: $names');
  print('Unique names set: $uniqueNames');
  print('Pages map: $pages');

  // 尝试添加错误类型（取消注释会报错）
  // names.add(42); // Error: The argument type 'int' can't be assigned to the parameter type 'String'

  // 2. 使用带构造函数的参数化类型
  print('\n--- 泛型构造函数示例 ---');
  var nameSet = Set<String>.from(names);
  print('Name set from list: $nameSet');

  // 3. 运行时类型检查
  print('\n--- 运行时类型检查 ---');
  // 由于names已经被声明为List<String>类型，所以直接打印其类型信息更有意义
  print('names的运行时类型: ${names.runtimeType}');
  print('nameSet is Set<int>: ${nameSet is Set<int>}'); // false

  // 4. 泛型类示例
  print('\n--- 泛型类示例 ---');
  var stringCache = MemoryCache<String>();
  stringCache.setByKey('name', 'Alice');
  print('String cache: ${stringCache.getByKey('name')}');

  var numberCache = MemoryCache<int>();
  numberCache.setByKey('age', 30);
  print('Number cache: ${numberCache.getByKey('age')}');

  // 5. 类型限制示例
  print('\n--- 类型限制示例 ---');
  var numberHolder = Holder<Number>(Number(42));
  print('Number holder: ${numberHolder.value}');

  // var objectHolder = Holder<Object>(42); // 错误: 类型参数不符合限制

  // 6. 泛型方法示例
  print('\n--- 泛型方法示例 ---');
  var firstNumber = first<int>([1, 2, 3]);
  print('First number: $firstNumber');

  var firstString = first<String>(['a', 'b', 'c']);
  print('First string: $firstString');

  // 7. F-bound示例
  print('\n--- F-bound示例 ---');
  var a1 = A(1);
  var a2 = A(2);
  print('Comparison result: ${compareAndOffset(a1, a2)}');
}

// 泛型缓存抽象类
abstract class Cache<T> {
  T getByKey(String key);
  void setByKey(String key, T value);
}

// 具体的内存缓存实现
class MemoryCache<T> implements Cache<T> {
  final Map<String, T> _cache = {};

  @override
  T getByKey(String key) => _cache[key] as T;

  @override
  void setByKey(String key, T value) {
    _cache[key] = value;
  }
}

// 类型限制示例类
class SomeBaseClass {
  @override
  String toString() => 'SomeBaseClass';
}

class Number {
  final int value;
  Number(this.value);

  @override
  String toString() => 'Number($value)';
}

class Holder<T extends Number> {
  final T value;
  Holder(this.value);
}

// 泛型方法示例
T first<T>(List<T> ts) {
  T tmp = ts[0];
  return tmp;
}

// F-bound示例
abstract interface class Comparable<T> {
  int compareTo(T o);
}

int compareAndOffset<T extends Comparable<T>>(T t1, T t2) =>
    t1.compareTo(t2) + 1;

class A implements Comparable<A> {
  final int value;

  A(this.value);

  @override
  int compareTo(A other) => value - other.value;

  @override
  String toString() => 'A($value)';
}
